package com.pactera.madp.cp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.cp.api.entity.WorkContactRoomEntity;
import com.pactera.madp.cp.api.entity.WorkRoomEntity;
import com.pactera.madp.cp.api.entity.daily.WorkContactRoomDailyEntity;
import com.pactera.madp.cp.api.entity.daily.WorkDailySendEntity;
import com.pactera.madp.cp.api.model.workroom.WorkContactRoomDailyIndexResp;
import com.pactera.madp.cp.api.model.workroom.WorkContactRoomDailyResp;
import com.pactera.madp.cp.api.util.Day;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.WorkContactRoomMapper;
import com.pactera.madp.cp.mapper.daily.WorkContactRoomDailyMapper;
import com.pactera.madp.cp.service.IWorkContactRoomDailyService;
import com.pactera.madp.cp.service.IWorkContactRoomService;
import com.pactera.madp.cp.service.IWorkDailySendService;
import com.pactera.madp.cp.service.IWorkRoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

@Service
public class WorkContactRoomDailyServiceImpl extends ServiceImpl<WorkContactRoomDailyMapper, WorkContactRoomDailyEntity> implements IWorkContactRoomDailyService {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @Autowired
    private IWorkDailySendService workDailySendService;
    @Resource
    private WorkContactRoomMapper workContactRoomMapper;
    @Resource
    private IWorkContactRoomService workContactRoomService;
    @Resource
    private IWorkRoomService workRoomService;

    @Override
    public WorkContactRoomDailyResp dailyQuery(String endDate, Integer dailyType) {
        Integer corpId = CorpContextHolder.getCorpId1();
        WorkDailySendEntity one = workDailySendService.getOne(Wrappers.<WorkDailySendEntity>query().eq("corp_id", corpId));
        if (Objects.isNull(one)) {
            return null;
        }

        Date date;
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        instance.set(Calendar.MILLISECOND, 0);
        date = instance.getTime();
        if (endDate != null) {
            try {
                date = sdf.parse(endDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime dateTime = instant.atZone(zoneId).toLocalDateTime();
        ArrayList<WorkContactRoomDailyIndexResp> workContactRoomDailyIndexResps = new ArrayList<>();
        //获取所需要的7个list
        List<WorkContactRoomDailyEntity> list = getLatest(dateTime, corpId, dailyType);
        Iterator<WorkContactRoomDailyEntity> iterator = list.iterator();
        //将list封装进返回对象中
        while (iterator.hasNext()) {
            WorkContactRoomDailyEntity next = iterator.next();
            Date createTime = Date.from(next.getCreateTime().atZone(ZoneId.systemDefault()).toInstant());
            WorkContactRoomDailyIndexResp workContactRoomDailyIndexResp = new WorkContactRoomDailyIndexResp();
            workContactRoomDailyIndexResp.setContactLossNum(next.getAddContact()- next.getChangeContact());
            workContactRoomDailyIndexResp.setTime(sdf.format(createTime));
            workContactRoomDailyIndexResp.setContactTotal(next.getTotalContact());
            workContactRoomDailyIndexResp.setContactAddNum(next.getChangeContact());
            workContactRoomDailyIndexResp.setContactRealAddNum(next.getRealAddContact());
            workContactRoomDailyIndexResp.setRoomAddNum(next.getChangeRoom());
            workContactRoomDailyIndexResp.setRoomTotal(next.getTotalRoom());
            workContactRoomDailyIndexResps.add(workContactRoomDailyIndexResp);
        }
        workContactRoomDailyIndexResps.sort(comparing(WorkContactRoomDailyIndexResp::getTime).reversed());
        WorkContactRoomDailyResp workContactRoomDailyResp = new WorkContactRoomDailyResp();
        //去最新一天数据将list和最新数据封装进返回对象
        WorkContactRoomDailyEntity lastCondition = getLastCondition(corpId, dailyType);
        workContactRoomDailyResp.setList(workContactRoomDailyIndexResps);
        workContactRoomDailyResp.setContactTotal(lastCondition.getTotalContact());
        workContactRoomDailyResp.setContactAddNum(lastCondition.getChangeContact());
        workContactRoomDailyResp.setContactRealAddNum(lastCondition.getAddContact());
        workContactRoomDailyResp.setRoomTotal(lastCondition.getTotalRoom());
        workContactRoomDailyResp.setRoomAddNum(lastCondition.getChangeRoom());
        workContactRoomDailyResp.setContactLossNum(lastCondition.getAddContact() - lastCondition.getChangeContact());
        List<String> room = getRoomList(one);
        workContactRoomDailyResp.setRoom(room);
        return workContactRoomDailyResp;
    }

    @Override
    public WorkContactRoomDailyIndexResp contactRoomDailyGenerate(Integer corpId, Integer dailyType, Day day) {
        LocalDate date;
        if (dailyType == 2) {
            date = day.getFirstDayOfWeek();
        } else if (dailyType == 3) {
            date = day.getFirstDayOfMonth();
        } else {
            date = LocalDate.now();
        }
        if (getNew(dailyType, corpId)) {
            WorkContactRoomDailyIndexResp first = getFirst(corpId,dailyType,date);
            return first;
        }

        WorkContactRoomDailyIndexResp workContactRoomDailyIndexResp = new WorkContactRoomDailyIndexResp();
        WorkContactRoomDailyEntity nowCondition = getNowCondition(corpId, dailyType);
        nowCondition.setCorpId(corpId);
        nowCondition.setDailyType(dailyType);
        nowCondition.setCreateTime(LocalDateTime.now());
        nowCondition.setCreateDay(date);
        this.save(nowCondition);

        //放进返回对象
        workContactRoomDailyIndexResp.setRoomAddNum(nowCondition.getChangeRoom());
        workContactRoomDailyIndexResp.setRoomTotal(nowCondition.getTotalRoom());
        workContactRoomDailyIndexResp.setContactTotal(nowCondition.getTotalContact());
        workContactRoomDailyIndexResp.setContactAddNum(nowCondition.getChangeContact());
        workContactRoomDailyIndexResp.setContactRealAddNum(nowCondition.getRealAddContact());
        workContactRoomDailyIndexResp.setContactLossNum(nowCondition.getAddContact() - nowCondition.getChangeContact());
        return workContactRoomDailyIndexResp;
    }
    //得到今天客户的记录
    WorkContactRoomDailyEntity getNowCondition(Integer corpId, Integer dailyType) {

        WorkContactRoomDailyEntity workContactRoomDailyEntity = new WorkContactRoomDailyEntity();
        //客群总数
        Integer totalRoom;
        //客群变化量
        Integer changeRoom;
        QueryWrapper<WorkRoomEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().select(WorkRoomEntity::getId, WorkRoomEntity::getRoomStatus).eq(WorkRoomEntity::getCorpId, corpId);
        //求新增   流失   所有客群
        List<WorkRoomEntity> allRooms = workRoomService.list(wrapper);
        //求总数    现存客群
        List<WorkRoomEntity> rooms = allRooms.stream().filter(room -> room.getRoomStatus() == 0).collect(Collectors.toList());
        totalRoom = rooms.size();

        WorkContactRoomDailyEntity entity = this.lambdaQuery()
                .eq(WorkContactRoomDailyEntity::getCorpId, corpId)
                .eq(WorkContactRoomDailyEntity::getDailyType, dailyType)
                .orderByDesc(WorkContactRoomDailyEntity::getCreateTime)
                .last("limit 1").list().get(0);


        changeRoom = totalRoom - entity.getTotalRoom();
        //客群数据
        workContactRoomDailyEntity.setTotalRoom(totalRoom);
        workContactRoomDailyEntity.setChangeRoom(changeRoom);
        //计算
        //客户总记录数
        Integer recordContact;
        //客户总数
        Integer totalContact = null;
        //客户变化量
        Integer changeContact;
        //客户净增量
        Integer RealAddContact;
        //不重复记录数
        Integer RealContact;
        //客户增加数
        Integer addContact;
        //所有客群的ids   计算
        List<Integer> allRoomIds;
        //未解散的客群ids
        List<Integer> roomIds;
        //获取客群客户总数
        if (rooms.size() != 0) {
            roomIds = rooms.stream().map(m -> m.getId()).collect(Collectors.toList());
            //获得总数
            totalContact = workContactRoomService.lambdaQuery().in(WorkContactRoomEntity::getRoomId, roomIds).count();
        }
        //计算增加客群客户数
        //使用所有客群计算总数
        allRoomIds = allRooms.stream().map(m -> m.getId()).collect(Collectors.toList());
        if (allRoomIds.size() < 0) allRoomIds.add(null);
        recordContact = workContactRoomMapper.selectByRoomIds(allRoomIds);
        WorkContactRoomDailyEntity lastCondition = getLastCondition(corpId, dailyType);
        //获得不重复客户关联记录数
        RealContact = workContactRoomMapper.selectDisId(allRoomIds);

        //获取净增
        RealAddContact = RealContact - lastCondition.getRealContact();
        //获取增加数
        addContact = recordContact - lastCondition.getRecordContact();
        // 客群客户变化数
        changeContact = totalContact - lastCondition.getTotalContact();

        // 客户数据
        workContactRoomDailyEntity.setRealContact(RealContact);
        workContactRoomDailyEntity.setAddContact(addContact);
        workContactRoomDailyEntity.setChangeContact(changeContact);
        workContactRoomDailyEntity.setRealAddContact(RealAddContact);
        workContactRoomDailyEntity.setTotalContact(totalContact);
        workContactRoomDailyEntity.setRecordContact(recordContact);
        return workContactRoomDailyEntity;
    }
    //获取昨天的记录
    WorkContactRoomDailyEntity getLastCondition(Integer corpId, Integer dailyType) {
        WorkContactRoomDailyEntity entity = new WorkContactRoomDailyEntity(0,0,0,0,0,0,0,0);
        entity.setCorpId(corpId);
        List<WorkContactRoomDailyEntity> list = this.lambdaQuery().eq(WorkContactRoomDailyEntity::getCorpId, corpId)
                .eq(WorkContactRoomDailyEntity::getDailyType, dailyType)
                .orderByDesc(WorkContactRoomDailyEntity::getCreateTime)
                .last("limit 1").list();
        if (list.size() != 0) {
            entity = list.get(0);
        }


        return entity;
    }
    //获取endDate最新前七个记录
    List<WorkContactRoomDailyEntity> getLatest(LocalDateTime endDate, Integer corpId, Integer dailyType) {

        List<WorkContactRoomDailyEntity> list = this.lambdaQuery().eq(WorkContactRoomDailyEntity::getCorpId, corpId)
                .eq(WorkContactRoomDailyEntity::getDailyType, dailyType)
                .le(WorkContactRoomDailyEntity::getCreateTime, endDate)
                .orderByDesc(WorkContactRoomDailyEntity::getCreateTime)
                .last("limit 7").list();
        //求出今天的总记录数
        return list;
    }
    //判定是否初次使用
    Boolean getNew(Integer dailyType, Integer corpId){
        int size = this.lambdaQuery().eq(WorkContactRoomDailyEntity::getDailyType, dailyType).eq(WorkContactRoomDailyEntity::getCorpId, corpId).count();
        if (size == 0) {
            return true;
        }
        return false;
    }
    //初次使用统计
    WorkContactRoomDailyIndexResp getFirst(Integer corpId, Integer dailyType, LocalDate date){
        WorkContactRoomDailyEntity workContactRoomDailyEntity = new WorkContactRoomDailyEntity();
        //每日客戶總數
        Integer totalContact;
        //记录总数
        Integer totalRecordContact;
        //记录总数
        Integer totalRealContact;
        //客户增长数
        Integer addContact;
        //客户净增数
        Integer realAddContact;
        //客户变化数
        Integer changeContact;
        //客群总数
        Integer totalRoom;
        List<WorkRoomEntity> workRoomEntities = workRoomService.selectAll(corpId);
        //获取客群总数
        totalRoom = workRoomService.lambdaQuery().eq(WorkRoomEntity::getRoomStatus, 0).eq(WorkRoomEntity::getCorpId, corpId).count();
        //获取所有的客群id
        List<Integer> roomIds = workRoomEntities.stream().map(m -> m.getId()).collect(Collectors.toList());

        workContactRoomDailyEntity.setTotalRoom(totalRoom);
        workContactRoomDailyEntity.setChangeRoom(totalRoom);

        workContactRoomDailyEntity.setCorpId(corpId);
        if (roomIds.size() == 0) roomIds.add(null);
        //获取总的关联数量来计算增加数
        //总记录数  计算客户新增
        totalRecordContact = workContactRoomService.selectByRoomIds(roomIds);
        //不重复记录数   计算客户净增
        totalRealContact = workContactRoomMapper.selectDisId(roomIds);
        //客户现存数，  计算变化数
        QueryWrapper<WorkContactRoomEntity> roomWrapper = new QueryWrapper<WorkContactRoomEntity>();
        roomWrapper.lambda().in(WorkContactRoomEntity::getId, roomIds);
        totalContact = workContactRoomService.list(roomWrapper).size();

        addContact = totalRecordContact;
        realAddContact = totalRealContact;
        changeContact = totalContact;

        workContactRoomDailyEntity.setChangeContact(changeContact);
        workContactRoomDailyEntity.setRealAddContact(realAddContact);
        workContactRoomDailyEntity.setAddContact(addContact);

        workContactRoomDailyEntity.setTotalContact(totalContact);
        workContactRoomDailyEntity.setRealContact(totalRealContact);
        workContactRoomDailyEntity.setRecordContact(totalRecordContact);

        workContactRoomDailyEntity.setCreateTime(LocalDateTime.now());
        workContactRoomDailyEntity.setDailyType(dailyType);
        this.save(workContactRoomDailyEntity);
        WorkContactRoomDailyIndexResp workContactRoomDailyIndexResp = new WorkContactRoomDailyIndexResp();

        workContactRoomDailyIndexResp.setRoomTotal(totalRoom);
        workContactRoomDailyIndexResp.setRoomAddNum(totalRoom);
        workContactRoomDailyIndexResp.setContactTotal(totalContact);
        workContactRoomDailyIndexResp.setContactAddNum(totalContact);
        workContactRoomDailyIndexResp.setContactRealAddNum(realAddContact);
        workContactRoomDailyIndexResp.setContactLossNum(totalRecordContact);
        workContactRoomDailyIndexResp.setTime(date.toString());

        return workContactRoomDailyIndexResp;
    }

    List<String> getRoomList(WorkDailySendEntity entity) {
        ArrayList<String> list = new ArrayList<>();
        if (entity.isTotalRoom()) list.add("roomTotal");
        if (entity.isChangeRoom()) list.add("roomAddNum");
        if (entity.isChangeContact()) list.add("contactAddNum");
        if (entity.isTotalContact()) list.add("contactTotal");
        if (entity.isRealAddContact()) list.add("contactRealAddNum");
        if (entity.isLossContact()) list.add("contactLossNum");
        return list;

    }

}
